//===--- CGFloat.swift.gyb ------------------------------------*- swift -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

%{

from SwiftIntTypes import *

# Number of bits in the Builtin.Word type
word_bits = int(CMAKE_SIZEOF_VOID_P) * 8

}%

@_exported import CoreGraphics
import Darwin

public struct CGFloat {
#if arch(i386) || arch(arm)
  /// The native type used to store the CGFloat, which is Float on
  /// 32-bit architectures and Double on 64-bit architectures.
  public typealias NativeType = Float
#elseif arch(x86_64) || arch(arm64)
  /// The native type used to store the CGFloat, which is Float on
  /// 32-bit architectures and Double on 64-bit architectures.
  public typealias NativeType = Double
#endif

  @_transparent public init() {
    self.native = 0.0
  }

  @_transparent public init(_ value: Float) {
    self.native = NativeType(value)
  }

  @_transparent public init(_ value: Double) {
    self.native = NativeType(value)
  }

  /// The native value.
  public var native: NativeType
}

@_transparent extension CGFloat : FloatingPointType {
  public typealias _BitsType = UInt

  public static func _fromBitPattern(bits: UInt) -> CGFloat {
    return CGFloat(NativeType._fromBitPattern(NativeType._BitsType(bits)))
  }

  public func _toBitPattern() -> UInt {
    return UInt(native._toBitPattern())
  }

% for src_ty in all_integer_types(word_bits):

  @_transparent public init(_ value: ${src_ty.stdlib_name}) {
    self.native = NativeType(value)
  }

% end

  public static var infinity: CGFloat {
    return CGFloat(NativeType.infinity)
  }

  public static var NaN: CGFloat {
    return CGFloat(NativeType.NaN)
  }

  public static var quietNaN: CGFloat {
    return CGFloat(NativeType.quietNaN)
  }

  public var isSignMinus: Bool {
    return native.isSignMinus
  }

  public var isNormal:  Bool {
    return native.isNormal
  }

  public var isFinite:  Bool {
    return native.isFinite
  }

  public var isZero:  Bool {
    return native.isZero
  }

  public var isSubnormal:  Bool {
    return native.isSubnormal
  }

  public var isInfinite:  Bool {
    return native.isInfinite
  }

  public var isNaN:  Bool {
    return native.isNaN
  }

  public var isSignaling: Bool {
    return native.isSignaling
  }

  public var floatingPointClass: FloatingPointClassification {
    return native.floatingPointClass
  }
}

extension CGFloat {
  @_transparent public static var min: CGFloat {
#if arch(i386) || arch(arm)
   return CGFloat(FLT_MIN)
#else
   return CGFloat(DBL_MIN)
#endif
  }

  @_transparent public static var max: CGFloat {
#if arch(i386) || arch(arm)
   return CGFloat(FLT_MAX)
#else
   return CGFloat(DBL_MAX)
#endif
  }
}

@available(*,unavailable,message="use CGFloat.min")
public var CGFLOAT_MIN: CGFloat {
  fatalError("can't retrieve unavailable property")
}

@available(*,unavailable,message="use CGFloat.max")
public var CGFLOAT_MAX: CGFloat {
  fatalError("can't retrieve unavailable property")
}

extension CGFloat : _Reflectable {
  /// Returns a mirror that reflects `self`.
  public func _getMirror() -> _MirrorType {
    return _reflect(native)
  }
}

@_transparent extension CGFloat : CustomStringConvertible {
  /// A textual representation of `self`.
  public var description: String {
    return native.description
  }
}

@_transparent extension CGFloat : Hashable {
  /// The hash value.
  ///
  /// **Axiom:** `x == y` implies `x.hashValue == y.hashValue`
  ///
  /// - Note: the hash value is not guaranteed to be stable across
  ///   different invocations of the same program.  Do not persist the
  ///   hash value across program runs.
  public var hashValue: Int {
    return native.hashValue
  }
}

@_transparent extension CGFloat : FloatLiteralConvertible {
  /// Create an instance initialized to `value`.
  public init(floatLiteral value: NativeType) {
    self = CGFloat(value)
  }
}

@_transparent extension CGFloat : IntegerLiteralConvertible {
  /// Create an instance initialized to `value`.
  public init(integerLiteral value: Int) {
    self = CGFloat(value)
  }
}

@_transparent extension CGFloat : AbsoluteValuable {
  /// Returns the absolute value of `x`
  @_transparent
  @warn_unused_result
  public static func abs(x: CGFloat) -> CGFloat {
    return CGFloat(NativeType.abs(x.native))
  }
}

% for dst_ty in all_integer_types(word_bits):

@_transparent extension ${dst_ty.stdlib_name} {
  public init(_ value: CGFloat) {
    self = ${dst_ty.stdlib_name}(value.native)
  }
}

% end


@_transparent extension Double {
  public init(_ value: CGFloat) {
    self = Double(value.native) 
  }
}

@_transparent extension Float {
  public init(_ value: CGFloat) {
    self = Float(value.native) 
  }
}

// Comparisons.
@_transparent extension CGFloat : Equatable { }

@_transparent
@warn_unused_result
public func ==(lhs: CGFloat, rhs: CGFloat) -> Bool {
  return lhs.native == rhs.native
}

@_transparent extension CGFloat : Comparable { }

@_transparent
@warn_unused_result
public func <(lhs: CGFloat, rhs: CGFloat) -> Bool {
  return lhs.native < rhs.native
}

@_transparent extension CGFloat : Strideable {
  /// Returns a stride `x` such that `self.advancedBy(x)` approximates
  /// `other`.
  ///
  /// - Complexity: O(1).
  @_transparent public
  func distanceTo(other: CGFloat) -> CGFloat {
    return CGFloat(other.native - self.native)
  }

  /// Returns a `Self` `x` such that `self.distanceTo(x)` approximates
  /// `n`.
  ///
  /// - Complexity: O(1).
  @_transparent public
  func advancedBy(amount: CGFloat) -> CGFloat {
    return CGFloat(self.native + amount.native)
  }
}

// CGFloat unary operators
@_transparent
@warn_unused_result
public prefix func + (x: CGFloat) -> CGFloat { return x }

@_transparent
@warn_unused_result
public prefix func - (x: CGFloat) -> CGFloat { return CGFloat(-x.native) }

@_transparent
public prefix func ++ (inout x: CGFloat) -> CGFloat {
  x.native += 1.0
  return x
}

@_transparent
public prefix func -- (inout x: CGFloat) -> CGFloat {
  x.native -= 1.0
  return x
}

@_transparent
public postfix func ++ (inout x: CGFloat) -> CGFloat {
  let tmp = x
  x.native += 1.0
  return tmp 
}

@_transparent
public postfix func -- (inout x: CGFloat) -> CGFloat {
  let tmp = x
  x.native -= 1.0
  return tmp 
}

// CGFloat arithmetic
@_transparent
@warn_unused_result
public func +(lhs: CGFloat, rhs: CGFloat) -> CGFloat {
  return CGFloat(lhs.native + rhs.native)
}

@_transparent
@warn_unused_result
public func -(lhs: CGFloat, rhs: CGFloat) -> CGFloat {
  return CGFloat(lhs.native - rhs.native)
}

@_transparent
@warn_unused_result
public func *(lhs: CGFloat, rhs: CGFloat) -> CGFloat {
  return CGFloat(lhs.native * rhs.native)
}

@_transparent
@warn_unused_result
public func /(lhs: CGFloat, rhs: CGFloat) -> CGFloat {
  return CGFloat(lhs.native / rhs.native)
}

@_transparent
@warn_unused_result
public func %(lhs: CGFloat, rhs: CGFloat) -> CGFloat {
  return CGFloat(lhs.native % rhs.native)
}

// CGFloat assignment operators.
@_transparent
public func +=(inout lhs: CGFloat, rhs: CGFloat) {
  lhs.native = lhs.native + rhs.native
}

@_transparent
public func -=(inout lhs: CGFloat, rhs: CGFloat) {
  lhs.native = lhs.native - rhs.native
}

@_transparent
public func *=(inout lhs: CGFloat, rhs: CGFloat) {
  lhs.native = lhs.native * rhs.native
}

@_transparent
public func /=(inout lhs: CGFloat, rhs: CGFloat) {
  lhs.native = lhs.native / rhs.native
}

@_transparent
public func %=(inout lhs: CGFloat, rhs: CGFloat) {
  lhs.native = lhs.native % rhs.native
}

// CGFloat tgmath.
@_transparent
@warn_unused_result
public func acos(x: CGFloat) -> CGFloat {
  return CGFloat(acos(x.native))
}

@_transparent
@warn_unused_result
public func cos(x: CGFloat) -> CGFloat {
  return CGFloat(cos(x.native))
}

@_transparent
@warn_unused_result
public func sin(x: CGFloat) -> CGFloat {
  return CGFloat(sin(x.native))
}

@_transparent
@warn_unused_result
public func asin(x: CGFloat) -> CGFloat {
  return CGFloat(asin(x.native))
}

@_transparent
@warn_unused_result
public func atan(x: CGFloat) -> CGFloat {
  return CGFloat(atan(x.native))
}

@_transparent
@warn_unused_result
public func tan(x: CGFloat) -> CGFloat {
  return CGFloat(tan(x.native))
}

@_transparent
@warn_unused_result
public func acosh(x: CGFloat) -> CGFloat {
  return CGFloat(acosh(x.native))
}

@_transparent
@warn_unused_result
public func asinh(x: CGFloat) -> CGFloat {
  return CGFloat(asinh(x.native))
}

@_transparent
@warn_unused_result
public func atanh(x: CGFloat) -> CGFloat {
  return CGFloat(atanh(x.native))
}

@_transparent
@warn_unused_result
public func cosh(x: CGFloat) -> CGFloat {
  return CGFloat(cosh(x.native))
}

@_transparent
@warn_unused_result
public func sinh(x: CGFloat) -> CGFloat {
  return CGFloat(sinh(x.native))
}

@_transparent
@warn_unused_result
public func tanh(x: CGFloat) -> CGFloat {
  return CGFloat(tanh(x.native))
}

@_transparent
@warn_unused_result
public func exp(x: CGFloat) -> CGFloat {
  return CGFloat(exp(x.native))
}

@_transparent
@warn_unused_result
public func exp2(x: CGFloat) -> CGFloat {
  return CGFloat(exp2(x.native))
}

@_transparent
@warn_unused_result
public func expm1(x: CGFloat) -> CGFloat {
  return CGFloat(expm1(x.native))
}

@_transparent
@warn_unused_result
public func log(x: CGFloat) -> CGFloat {
  return CGFloat(log(x.native))
}

@_transparent
@warn_unused_result
public func log10(x: CGFloat) -> CGFloat {
  return CGFloat(log10(x.native))
}

@_transparent
@warn_unused_result
public func log2(x: CGFloat) -> CGFloat {
  return CGFloat(log2(x.native))
}

@_transparent
@warn_unused_result
public func log1p(x: CGFloat) -> CGFloat {
  return CGFloat(log1p(x.native))
}

@_transparent
@warn_unused_result
public func logb(x: CGFloat) -> CGFloat {
  return CGFloat(logb(x.native))
}

@_transparent
@warn_unused_result
public func cbrt(x: CGFloat) -> CGFloat {
  return CGFloat(cbrt(x.native))
}

@_transparent
@warn_unused_result
public func erf(x: CGFloat) -> CGFloat {
  return CGFloat(erf(x.native))
}

@_transparent
@warn_unused_result
public func erfc(x: CGFloat) -> CGFloat {
  return CGFloat(erfc(x.native))
}

@_transparent
@warn_unused_result
public func tgamma(x: CGFloat) -> CGFloat {
  return CGFloat(tgamma(x.native))
}

@_transparent
@warn_unused_result
public func fabs(x: CGFloat) -> CGFloat {
  return CGFloat(fabs(x.native))
}

@_transparent
@warn_unused_result
public func sqrt(x: CGFloat) -> CGFloat {
  return CGFloat(sqrt(x.native))
}

@_transparent
@warn_unused_result
public func ceil(x: CGFloat) -> CGFloat {
  return CGFloat(ceil(x.native))
}

@_transparent
@warn_unused_result
public func floor(x: CGFloat) -> CGFloat {
  return CGFloat(floor(x.native))
}

@_transparent
@warn_unused_result
public func nearbyint(x: CGFloat) -> CGFloat {
  return CGFloat(nearbyint(x.native))
}

@_transparent
@warn_unused_result
public func rint(x: CGFloat) -> CGFloat {
  return CGFloat(rint(x.native))
}

@_transparent
@warn_unused_result
public func round(x: CGFloat) -> CGFloat {
  return CGFloat(round(x.native))
}

@_transparent
@warn_unused_result
public func trunc(x: CGFloat) -> CGFloat {
  return CGFloat(trunc(x.native))
}

@_transparent
@warn_unused_result
public func atan2(lhs: CGFloat, _ rhs: CGFloat) -> CGFloat {
  return CGFloat(atan2(lhs.native, rhs.native))
}

@_transparent
@warn_unused_result
public func hypot(lhs: CGFloat, _ rhs: CGFloat) -> CGFloat {
  return CGFloat(hypot(lhs.native, rhs.native))
}

@_transparent
@warn_unused_result
public func pow(lhs: CGFloat, _ rhs: CGFloat) -> CGFloat {
  return CGFloat(pow(lhs.native, rhs.native))
}

@_transparent
@warn_unused_result
public func fmod(lhs: CGFloat, _ rhs: CGFloat) -> CGFloat {
  return CGFloat(fmod(lhs.native, rhs.native))
}

@_transparent
@warn_unused_result
public func remainder(lhs: CGFloat, _ rhs: CGFloat) -> CGFloat {
  return CGFloat(remainder(lhs.native, rhs.native))
}

@_transparent
@warn_unused_result
public func copysign(lhs: CGFloat, _ rhs: CGFloat) -> CGFloat {
  return CGFloat(copysign(lhs.native, rhs.native))
}

@_transparent
@warn_unused_result
public func nextafter(lhs: CGFloat, _ rhs: CGFloat) -> CGFloat {
  return CGFloat(nextafter(lhs.native, rhs.native))
}

@_transparent
@warn_unused_result
public func fdim(lhs: CGFloat, _ rhs: CGFloat) -> CGFloat {
  return CGFloat(fdim(lhs.native, rhs.native))
}

@_transparent
@warn_unused_result
public func fmax(lhs: CGFloat, _ rhs: CGFloat) -> CGFloat {
  return CGFloat(fmax(lhs.native, rhs.native))
}

@_transparent
@warn_unused_result
public func fmin(lhs: CGFloat, _ rhs: CGFloat) -> CGFloat {
  return CGFloat(fmin(lhs.native, rhs.native))
}

@_transparent
@warn_unused_result
public func fpclassify(x: CGFloat) -> Int {
  return fpclassify(x.native)
}

@_transparent
@warn_unused_result
public func isnormal(x: CGFloat) -> Bool {
  return isnormal(x.native)
}

@_transparent
@warn_unused_result
public func isfinite(x: CGFloat) -> Bool {
  return isfinite(x.native)
}

@_transparent
@warn_unused_result
public func isinf(x: CGFloat) -> Bool {
  return isinf(x.native)
}

@_transparent
@warn_unused_result
public func isnan(x: CGFloat) -> Bool {
  return isnan(x.native)
}

@_transparent
@warn_unused_result
public func signbit(x: CGFloat) -> Int {
  return signbit(x.native)
}

@_transparent
@warn_unused_result
public func modf(x: CGFloat) -> (CGFloat, CGFloat) {
  let (ipart, fpart) = modf(x.native)
  return (CGFloat(ipart), CGFloat(fpart))
}

@_transparent
@warn_unused_result
public func ldexp(x: CGFloat, _ n: Int) -> CGFloat {
  return CGFloat(ldexp(x.native, n))
}

@_transparent
@warn_unused_result
public func frexp(x: CGFloat) -> (CGFloat, Int) {
  let (frac, exp) = frexp(x.native)
  return (CGFloat(frac), exp)
}

@_transparent
@warn_unused_result
public func ilogb(x: CGFloat) -> Int {
  return ilogb(x.native)
}

@_transparent
@warn_unused_result
public func scalbn(x: CGFloat, _ n: Int) -> CGFloat {
  return CGFloat(scalbn(x.native, n))
}

@_transparent
@warn_unused_result
public func lgamma(x: CGFloat) -> (CGFloat, Int) {
  let (value, sign) = lgamma(x.native)
  return (CGFloat(value), sign)
}

@_transparent
@warn_unused_result
public func remquo(x: CGFloat, _ y: CGFloat) -> (CGFloat, Int) {
  let (rem, quo) = remquo(x.native, y.native)
  return (CGFloat(rem), quo)
}

@_transparent
@warn_unused_result
public func nan(tag: String) -> CGFloat {
  return CGFloat(nan(tag) as CGFloat.NativeType)
}

@_transparent
@warn_unused_result
public func fma(x: CGFloat, _ y: CGFloat, _ z: CGFloat) -> CGFloat {
  return CGFloat(fma(x.native, y.native, z.native))
}

@_transparent
@warn_unused_result
public func j0(x: CGFloat) -> CGFloat {
  return CGFloat(j0(Double(x.native)))
}

@_transparent
@warn_unused_result
public func j1(x: CGFloat) -> CGFloat {
  return CGFloat(j1(Double(x.native)))
}

@_transparent
@warn_unused_result
public func jn(n: Int, _ x: CGFloat) -> CGFloat {
  return CGFloat(jn(n, Double(x.native)))
}

@_transparent
@warn_unused_result
public func y0(x: CGFloat) -> CGFloat {
  return CGFloat(y0(Double(x.native)))
}

@_transparent
@warn_unused_result
public func y1(x: CGFloat) -> CGFloat {
  return CGFloat(y1(Double(x.native)))
}

@_transparent
@warn_unused_result
public func yn(n: Int, _ x: CGFloat) -> CGFloat {
  return CGFloat(yn(n, Double(x.native)))
}

@_transparent
extension CGFloat : _CVarArgPassedAsDouble, _CVarArgAlignedType {
  /// Transform `self` into a series of machine words that can be
  /// appropriately interpreted by C varargs
  public var _cVarArgEncoding: [Int] {
    return native._cVarArgEncoding
  }

  /// Return the required alignment in bytes of 
  /// the value returned by `_cVarArgEncoding`.
  public var _cVarArgAlignment: Int { 
    return native._cVarArgAlignment
  }
}
